package com.google.guava.concurrent;

import com.google.common.base.Stopwatch;
import com.google.common.util.concurrent.RateLimiter;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.Thread.currentThread;

/**
 * @author fuc
 * @create 2020-10-11
 */
public class TokenBucket {
  private AtomicInteger phoneNumbers = new AtomicInteger(0);

  private static final int LiMIT = 100;

  private RateLimiter rateLimiter = RateLimiter.create(10);

  private final int saleLimit;

  public TokenBucket() {
    this(LiMIT);
  }

  public TokenBucket(int limit) {
    this.saleLimit = limit;
  }

  public int buy() {
    Stopwatch started = Stopwatch.createStarted();
    boolean success = rateLimiter.tryAcquire(10, TimeUnit.SECONDS);
    if (success) {
      if (phoneNumbers.get() >= saleLimit) {
        throw new IllegalStateException("Not any phone can be sale,please wait to next time.");
      }
      int phoneNo = phoneNumbers.getAndIncrement();
      handleOrder();
      System.out.println(
          currentThread() + "user get the Mi phone:" + phoneNo + ",ELT:" + started.stop());
      return phoneNo;
    } else {
      started.stop();
      throw new RuntimeException("Sorry,occur exception when buy phone");
    }
  }

  private void handleOrder() {
    try {
      TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
